package edu.szte.ovrt.datahandler.xml;

import java.io.Reader;

import javax.xml.stream.*;

import edu.szte.ovrt.datahandler.core.AbstractDocumentReader;
import edu.szte.ovrt.datahandler.core.DocumentReaderException;
import edu.szte.ovrt.datahandler.model.*;

public class XMLReader extends AbstractDocumentReader implements XMLConstants {
	private static final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
	private final XMLStreamReader m_xmlReader;

	public XMLReader(final Reader reader) throws XMLStreamException {
		super(reader);
		m_xmlReader = inputFactory.createXMLStreamReader(reader);
	}

	@Override
	public Document readDocument() throws DocumentReaderException {
		final Document document = new Document();
		try {
			m_xmlReader.nextTag(); // go to <Document...
			Section section = null;
			while (m_xmlReader.nextTag() == XMLStreamConstants.START_ELEMENT //
					&& "Section".equals(m_xmlReader.getLocalName()) //
					&& (section = readSection(document)) != null) {
				document.addSection(section);
				if (m_xmlReader.getEventType() == XMLStreamConstants.END_ELEMENT //
						&& "Document".equals(m_xmlReader.getLocalName())) {
					break;
				}
			}
		} catch (final XMLStreamException e) {
			throw new DocumentReaderException(e);
		} finally {
			try {
				m_xmlReader.close();
			} catch (final XMLStreamException e) {/* no op */}
		}
		return document;
	}

	private Section readSection(final Document document) throws XMLStreamException {
		final Section section = new Section(document);
		section.setName(m_xmlReader.getAttributeValue(null, "name"));
		Item item = null;
		while (m_xmlReader.nextTag() == XMLStreamConstants.START_ELEMENT //
				&& "Item".equals(m_xmlReader.getLocalName()) //
				&& (item = readItem(section)) != null) {
			section.addItem(item);
		}
		return section;
	}

	private Item readItem(final Section section) throws XMLStreamException {
		final String key = m_xmlReader.getAttributeValue(null, "key");
		final String value = m_xmlReader.getAttributeValue(null, "value");
		m_xmlReader.nextTag(); // skip to </Item>
		return new Item(section, key, value);
	}
}
